package cn.gs.global.server.meta;

// @author gs
import cn.gs.db.BoolTransaction;
import cn.gs.global.common.meta.IObjServer;
import cn.gs.global.common.meta.ObjInfo;
import cn.gs.global.table.meta.Obj;
import cn.gs.util.set.ArrayUtil;
import cn.gs.util.set.Pair;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

public class ObjServer extends IdNameServer<Obj> implements IObjServer {

    MetaCore core;

    public ObjServer(MetaCore core) {
        super(Obj.class, "Obj", core.getUtil());
        this.core = core;
    }

    public void set(ObjInfo... infos) {
        for (ObjInfo in : infos) {
            setFol(in.getObjId(), in.getIds(), in.getFols());
            setChg(in.getObjId(), in.getIds(), in.getChgs());
        }
    }

    @Override
    public void setFol(final int objId, final int[] ids, final double[] values) {
        util.transaction(new BoolTransaction() {

            @Override
            public boolean work() {
                Obj obj = util.get(clazz, objId);
                if (obj != null && ids != null && values != null) {
                    for (int i = 0, len = Math.min(ids.length, values.length); i < len; ++i) {
                        Obj o = util.get(clazz, ids[i]);
                        obj.folCount(o, values[i]);
                    }
                }
                util.saveOrUpdate(obj);
                return true;
            }
        });
    }

    @Override
    public void setChg(final int objId, final int[] ids, final double[] values) {
        util.transaction(new BoolTransaction() {

            @Override
            public boolean work() {
                Obj obj = util.get(clazz, objId);
                if (obj != null && ids != null && values != null) {
                    for (int i = 0, len = Math.min(ids.length, values.length); i < len; ++i) {
                        Obj o = util.get(clazz, ids[i]);
                        obj.chgCount(o, values[i]);
                    }
                }
                util.saveOrUpdate(obj);
                return true;
            }
        });
    }

    @Override
    public ObjInfo[] info(int... ids) {
        List<Integer> objIds = ArrayUtil.array2List(ids);
        List<Obj> objs = util.get(clazz, objIds);
        ObjInfo[] infos = new ObjInfo[objs.size()];
        int i = 0;
        for (Obj o : objs) {
            infos[i++] = info(o);
        }
        return infos;
    }

    ObjInfo info(Obj obj) {;
        Map<Obj, Pair<Double, Double>> map = new HashMap<>();
        for (Entry<Obj, Double> e : obj.getFol().entrySet()) {
            Pair<Double, Double> p = map.get(e.getKey());
            if (p == null) {
                p = new Pair<>(0.0, 0.0);
                map.put(e.getKey(), p);
            }
            p.setFirst(e.getValue());
        }
        for (Entry<Obj, Double> e : obj.getChg().entrySet()) {
            Pair<Double, Double> p = map.get(e.getKey());
            if (p == null) {
                p = new Pair<>(0.0, 0.0);
                map.put(e.getKey(), p);
            }
            p.setSecond(e.getValue());
        }
        int[] ids = new int[map.size()];
        double[] fols = new double[map.size()], chgs = new double[map.size()];
        int i = 0;
        for (Entry<Obj, Pair<Double, Double>> e : map.entrySet()) {
            ids[i] = e.getKey().getId();
            fols[i] = e.getValue().getFirst();
            chgs[i] = e.getValue().getSecond();
            ++i;
        }
        ObjInfo info = new ObjInfo();
        info.setTime(core.date());
        info.setObjId(obj.getId());
        info.setIds(ids);
        info.setFols(fols);
        info.setChgs(chgs);
        return info;
    }
}
